package org.noote.libs.roby.scan;

// Not use now
public class ScanResult {

	protected int _x=0, _y=0;
	protected short [] _scanbuffer = null;
	
	public int low_step = 1, high_step = 1;
	public int low_start = 0, low_end = 180;
	public int high_start = 0, high_end = 180;
	
	public ScanResult()
	{
	}
	
	public ScanResult(int x, int y)
	{
		createBuffer(x, y);
	}
	
	public int getWidth()
	{
		return _x;
	}
	public int getHeight()
	{
		return _y;
	}

	public boolean createBuffer(int x, int y)
	{
		_x=x;
		_y=y;
		_scanbuffer = new short[_x*_y];
		
		return _scanbuffer!=null;
	}
	
	public void fill(short v)
	{
		for(int s=0; s<_x*_y; s++)
			_scanbuffer[s] = v;
	}
	public void set(int x, int y, short v)
	{
		if(x>=0 && x<_x && y>=0 && y<_y)
			_scanbuffer[y*_x + x] = v;
	}
	public short get(int x, int y)
	{
		if(x>=0 && x<_x && y>=0 && y<_y)
			return _scanbuffer[y*_x + x];
		
		return 0;
	}
	
	public short getReal(int iL, int iH)
	{
		if(iL>=low_start && iL<=low_end
			&& iH>=high_start && iH<=high_end)
		{
			int x=(iL-low_start)/low_step;
			int y=(iH-high_start)/high_step;
			
			return get(x, y);
		}
		return 0;
	}
	
	public boolean parseScanZone(String sData)
	{
		low_step = -1; high_step = -1;
		low_start = -1; low_end = -1;
		high_start = -1; high_end = -1;

		String [] sParams = sData.split("\\,");
		for(String p : sParams)
		{
			String [] sVals = p.split("\\=");
			if(sVals.length != 2) continue;
			
			String name = sVals[0].trim();
			String val = sVals[1].trim();
			
			if(name.equals("low_step")) low_step = Integer.parseInt(val);
			else if(name.equals("high_step")) high_step = Integer.parseInt(val);
			else if(name.equals("low_start")) low_start = Integer.parseInt(val);
			else if(name.equals("low_end")) low_end = Integer.parseInt(val);
			else if(name.equals("high_start")) high_start = Integer.parseInt(val);
			else if(name.equals("high_end")) high_end = Integer.parseInt(val);
			else if(name.equals("data"))
			{
				// missing data ?
				if(low_step==-1 || high_step==-1 || low_start==-1 || low_end==-1 || high_start==-1 || high_end==-1)
					return false;
				
				// create buffer
				if(!createBuffer(low_end-low_start, high_end-high_start))
					return false;
				
				fill((short)-1);
				
				//
        		String [] sDatas = val.split("\\;");
        		for(String d : sDatas)
        		{
        			String [] sD = d.split("\\ ");
        			if(sD.length != 3) continue;
        			
        			String sL = sD[0].trim();
        			String sH = sD[1].trim();
        			String sV = sD[2].trim();

        			int l = Integer.parseInt(sL);
        			int h = Integer.parseInt(sH);
        			short v = Short.parseShort(sV);

    				l = low_end-(l-low_start);
    				h = high_end-(h-high_start);
    				for(int x=0; x<low_step && (l+x-low_start)<getWidth(); x++)
    				{
        				for(int y=0; y<high_step && (h+y-high_start)<getHeight(); y++)
        				{
        					set(l+x-low_start, h+y-high_start, v);
        				}
    				}
        		}
			}
		}
		
		return true;
	}

	public boolean parseScanLine(String sData)
	{
		low_step = -1; high_step = 1;
		low_start = -1; low_end = -1;
		high_start = -1; high_end = -1;

		String [] sParams = sData.split("\\,");
		for(String p : sParams)
		{
			String [] sVals = p.split("\\=");
			if(sVals.length != 2) continue;
			
			String name = sVals[0].trim();
			String val = sVals[1].trim();
			
			if(name.equals("low_step")) low_step = Integer.parseInt(val);
			else if(name.equals("low_start")) low_start = Integer.parseInt(val);
			else if(name.equals("low_end")) low_end = Integer.parseInt(val);
			else if(name.equals("high")) high_start = high_end = Integer.parseInt(val);
			else if(name.equals("data"))
			{
				// missing data ?
				if(low_step==-1 || high_step==-1 || low_start==-1 || low_end==-1 || high_start==-1 || high_end==-1)
					return false;
				
				// create buffer
				if(!createBuffer(low_end-low_start, 1))
					return false;
				
				fill((short)-1);
				
				//
        		String [] sDatas = val.split("\\;");
        		for(String d : sDatas)
        		{
        			String [] sD = d.split("\\ ");
        			if(sD.length != 3) continue;
        			
        			String sL = sD[0].trim();
        			String sH = sD[1].trim();
        			String sV = sD[2].trim();

        			int l = Integer.parseInt(sL);
        			@SuppressWarnings("unused")
					int h = Integer.parseInt(sH);
        			short v = Short.parseShort(sV);

    				l = low_end-(l-low_start);
    				for(int x=0; x<low_step && (l+x-low_start)<getWidth(); x++)
    				{
    					set(l+x-low_start, 0, v);
    				}
        		}
			}
		}
		
		return true;
	}
	
	public void correction()
	{
		int notfilled = 0;
		{
			for(int y=0; y<_y; y++)
			{
				for(int x=0; x<_x; x++)
				{
					// bad result find ?
					if(get(x, y) == -1)
					{
						long t=0;
						int c=0;
						
						short xAyA = get(x-1, y-1);
						short xAyB = get(x-1, y);
						short xAyC = get(x-1, y+1);
						short xByA = get(x, y-1);
						short xByC = get(x, y+1);
						short xCyA = get(x+1, y-1);
						short xCyB = get(x+1, y);
						short xCyC = get(x+1, y+1);
						
						if(xAyA > 0) {t+=xAyA; c++;}
						if(xAyB > 0) {t+=xAyB; c++;}
						if(xAyC > 0) {t+=xAyC; c++;}
						if(xByA > 0) {t+=xByA; c++;}
						if(xByC > 0) {t+=xByC; c++;}
						if(xCyA > 0) {t+=xCyA; c++;}
						if(xCyB > 0) {t+=xCyB; c++;}
						if(xCyC > 0) {t+=xCyC; c++;}
	
						if(c>0)
						{
							short cor = (short)(t/c);  
							set(x, y, cor);
						}
						else notfilled++;
					}
				}
			}
		} while(notfilled>0);
	}
	
	public void smooth()
	{
		short [] _scanbuffer2 = new short[_x*_y];
		
		for(int y=0; y<_y; y++)
		{
			for(int x=0; x<_x; x++)
			{
				long t=0;
				int c=0;
				
				short xAyA = get(x-1, y-1);
				short xAyB = get(x-1, y);
				short xAyC = get(x-1, y+1);
				short xByA = get(x, y-1);
				short xByB = get(x, y);
				short xByC = get(x, y+1);
				short xCyA = get(x+1, y-1);
				short xCyB = get(x+1, y);
				short xCyC = get(x+1, y+1);
				
				if(xAyA > 0) {t+=xAyA; c++;}
				if(xAyB > 0) {t+=xAyB; c++;}
				if(xAyC > 0) {t+=xAyC; c++;}
				if(xByA > 0) {t+=xByA; c++;}
				if(xByB > 0) {t+=xByB; c++;}
				if(xByC > 0) {t+=xByC; c++;}
				if(xCyA > 0) {t+=xCyA; c++;}
				if(xCyB > 0) {t+=xCyB; c++;}
				if(xCyC > 0) {t+=xCyC; c++;}
				
				_scanbuffer2[y*_x+x] = (short)(t/c);
			}
		}
		
		_scanbuffer = _scanbuffer2;
	}
	
	static public String toString(ScanResult scan)
	{
		String sRet = "";
		sRet += "low_step=" + Integer.toString(scan.low_start);
		sRet += ",low_start=" + Integer.toString(scan.low_start);
		sRet += ",low_end=" + Integer.toString(scan.low_end);
		sRet += ",high_step=" + Integer.toString(scan.high_step);
		sRet += ",high_start=" + Integer.toString(scan.high_start);
		sRet += ",high_end=" + Integer.toString(scan.high_end);
		sRet += ",data=";
		for(int y=0; y<scan.getHeight(); y++)
		{
			for(int x=0; x<scan.getWidth(); x++)
			{
				sRet += Integer.toString(x) + " " + Integer.toString(y) + " ";
				sRet += Short.toString(scan.getReal(x, y)) + ";";
			}
		}
		
		return sRet;
	}
}
